package com.alan.product.issue.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 */
@Slf4j
public class JwtUtils {

    /**
     * 发布者
     */
    private static final String ISSUER = "GATEWAY";

    /**
     * 密钥
     */
    private static final String SECRET = "xxxxxxxxx";

    /**
     * 过期时间10天，时间设置长一点，防止积压在kafka中的消息处理不完
     */
    private static final long EXPIRED_TIME = 10 * 24 * 3600 * 1000;

    public static String newJwtToken(CurrentUser currentUser) {
        JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(currentUser));
        Map<String, String> params = new HashMap<>(8);
        for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
            if (entry.getKey() != null && entry.getValue() != null) {
                params.put(entry.getKey(), entry.getValue().toString());
            }
        }
        return newJwtToken(params);
    }

    public static String newJwtToken(Map<String, String> params) {
        Date now = new Date();
        JWTCreator.Builder builder = JWT.create()
                .withIssuer(ISSUER)
                .withIssuedAt(new Date(now.getTime() - 5000))
//                .withIssuedAt(now)
                .withExpiresAt(new Date(now.getTime() + EXPIRED_TIME));

        if (!params.isEmpty()) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                builder.withClaim(entry.getKey(), entry.getValue());
            }
        }

        return builder.sign(Algorithm.HMAC256(SECRET));
    }

    public static Map<String, String> parseJwtToken(String jwtToken) {
        Map<String, String> map = new HashMap<>(8);

        if (jwtToken == null || jwtToken.isEmpty()) {
            log.info("jwtToken is empty, anything wrong?");
        } else  {
            try {
                DecodedJWT decodedJWT = JWT.require(Algorithm.HMAC256(SECRET))
                        .withIssuer(ISSUER)
                        .build()
                        .verify(jwtToken);

                for (Map.Entry<String, Claim> entry : decodedJWT.getClaims().entrySet()) {
                    map.put(entry.getKey(), entry.getValue().asString());
                }
            } catch (Exception e) {
                log.error("parse jwtToken error, jwtToken={}", jwtToken, e);
            }
        }

        return map;
    }

    @Data
    public static class CurrentUser {
        private String userId;
    }

    public static void main(String[] args) {
        CurrentUser currentUser = new CurrentUser();
        currentUser.setUserId("123456");

        String jwtToken = newJwtToken(currentUser);
        System.out.println(jwtToken);
        System.out.println(parseJwtToken(jwtToken));
    }
}
